home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 34.zip / BS1 part 34 / FredFish PD 304.adf / IRA / ira.c < prev    next >
C/C++ Source or Header  |  1990-01-10  |  11KB  |  571 lines

  1. /*
  2.  *  IRA : IRA Calculator
  3.  *
  4.  *    Version 2
  5.  *
  6.  *    by Joel Swank 9-26-89
  7.  *
  8.  */
  9.  
  10. /********* INCLUDES ************************ */
  11.  
  12.  
  13. #include <exec/types.h>
  14. #include <exec/io.h>
  15. #include <exec/memory.h>
  16. #include <libraries/dos.h>
  17. #include <intuition/intuition.h>
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include "fio.h"
  21. #include "limits.h"
  22.  
  23.  
  24. /* Data in helpwin.h  */
  25. extern struct IntuiText prfailtxt ;
  26. extern struct IntuiText badfiletxt ;
  27. extern struct IntuiText fiofailtxt ;
  28. extern struct IntuiText winfailtxt ;
  29. extern struct IntuiText messagetxt ;
  30. extern struct IntuiText infailtxt ;
  31. extern struct IntuiText infailtxt2 ;
  32. extern struct IntuiText oktxt ;
  33. extern struct IntuiText cantxt ;
  34. extern struct IntuiText retrytxt ;
  35. extern struct NewWindow    NewWindowStructureHelp;
  36. extern struct NewWindow    NewWindowStructure3;
  37. extern char message_buff[];
  38.  
  39. /* Data in doargs.c   */
  40. extern char filename[];
  41.  
  42. /* Defines for setting/clearing GADGDISABLED flag */
  43. #define OffGad(gad) (gad).Flags = gad.Flags | GADGDISABLED
  44. #define OnGad(gad) (gad).Flags = gad.Flags & ~(GADGDISABLED)
  45. #define OffMenu(item) (item).Flags = item.Flags & ~(CHECKED)
  46. #define OnMenu(item) (item).Flags = item.Flags | CHECKED
  47.  
  48.  
  49.  
  50. extern struct IntuitionBase *IntuitionBase ;
  51. extern struct GfxBase *GfxBase ;
  52. extern struct DosLibrary *DosBase ;
  53.  
  54. struct ViewPort vP;
  55. struct Window *wG = NULL;
  56. struct Window *wF = NULL;
  57. struct RastPort *rpG;
  58. struct IntuiMessage *message;    /* the message from the IDCMP */
  59.  
  60. struct Window *OpenWindow();
  61. void *OpenLibrary();
  62. struct IntuiMessage *GetMsg();
  63. struct MenuItem *ItemAddress();
  64.  
  65. struct FileIOSupport *FIOSupp = NULL;      /* fileio support stuff */
  66. struct FileIOSupport *GetFileIOSupport();
  67. struct FileLock *Lock();
  68. char save_title[] = "Select File to SAVE";
  69. char load_title[] = "Select File to LOAD";
  70.  
  71. /* get the PowerWindows 2.0 code */
  72. #include "ira.h"
  73.  
  74. /* internal data areas */
  75. char balancemsg[] = "Invalid Balance";
  76. char interestmsg[] = "Invalid Interest";
  77. char depositmsg[] = "Invalid Deposit";
  78. char yearsmsg[] = "Invalid Years";
  79. char header[] = "IRA Calculator";
  80.  
  81. /*    The input data    */
  82. double apr = 0.0;        /* Anual percentage rate  (-a) */
  83. double bb = 0.0;         /* Beginning balance      (-b) */
  84. double ad = 0.0;         /* Annual Deposit         (-d) */
  85. long  yrs = 0;           /* Years till retirement  (-y) */
  86.  
  87. /*    The Answer        */
  88. double ne = 0.0;         /* final total */
  89.  
  90. char *name;
  91. int batch = 0;           /* flag for a batch (CLI) execution */
  92.  
  93. double atof();
  94. long atol();
  95.  
  96.  
  97.  
  98. main(argc,argv)
  99. int argc;
  100. char *argv[];
  101. {
  102.     UWORD code;
  103.     ULONG class;
  104.     APTR object;
  105.     FILE *fp;
  106.  
  107.  
  108.     /* Open the libraries */
  109.  
  110.     IntuitionBase = (struct IntuitionBase *)
  111.         OpenLibrary("intuition.library", 0L);
  112.     if (IntuitionBase == NULL)
  113.         {
  114.         done(11);
  115.         }
  116.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L);
  117.     if (GfxBase == NULL)
  118.         {
  119.         done(10);
  120.         }
  121.  
  122.     DosBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
  123.     if (DosBase == NULL)
  124.         {
  125.         done(16);
  126.         }
  127.  
  128.     /*   Get the arguments */
  129.  
  130.     filename[0] = '\0';
  131.  
  132.     if (argc == 0) getWBargs();
  133.     else getCLIargs(argc,argv);
  134.     if (batch)
  135.         {
  136.         calc_it();
  137.         done(0);
  138.         }
  139.  
  140.     wG = OpenWindow(&NewWindowStructure1);    /* open main window */
  141.     if ( wG == NULL )
  142.         {
  143.         done(12);
  144.         }
  145.  
  146.     rpG = wG->RPort;    /* get a rastport pointer for the window */
  147.  
  148.     PrintIText(rpG,&IntuiTextList1,0L,0L); /* write window text */
  149.  
  150.     SetMenuStrip(wG,&MenuList1);    /* attach my Menu */
  151.  
  152.     if (filename[0] != '\0')
  153.         {
  154.         while ((fp = fopen(filename,"r")) == NULL)
  155.             {
  156.             infailtxt2.IText = (UBYTE *) filename;
  157.             if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
  158.                 0L,0L,reqlen(filename),75L)) continue;
  159.             }
  160.         if (fp != NULL) {
  161.             read_file(fp);
  162.             fclose(fp);
  163.             }
  164.         }
  165.  
  166.     /* Wait for some User interaction */
  167.     while(1)
  168.     {
  169.         WaitPort(wG->UserPort);
  170.             while( (message = (struct IntuiMessage *)
  171.                 GetMsg(wG->UserPort) ) != NULL)
  172.             {
  173.                 code = message->Code;  /* MENUNUM */
  174.                 object = message->IAddress;  /* Gadget */
  175.                 class = message->Class;  /* IDCMP Flags */
  176.                 ReplyMsg(message);  /* Free the sender */
  177.                 switch (class)
  178.                     {
  179.                     case CLOSEWINDOW :
  180.                         done(0);   /* close gadget clicked */
  181.                     case GADGETUP:
  182.                         if (object == (APTR) &CalcGad)
  183.                             {
  184.                             calc_it();
  185.                             break;
  186.                             }
  187.                         /* add more gadget checks here */
  188.                         break;
  189.                     case MENUPICK:    /* menu selection made */
  190.                         /* I get a NULL message whenever the user brings
  191.                            up the menu but doesn't select anything    */
  192.                         if (code != MENUNULL) do_pick((USHORT)code);
  193.                         break;
  194.                     }
  195.             }
  196.     } 
  197. }
  198.  
  199. /*
  200.  * Cleanup and exit
  201.  */
  202.  
  203. done(how)
  204. int how;
  205. {
  206.     if (FIOSupp) ReleaseFileIO(FIOSupp);
  207.     if (wG) ClearMenuStrip(wG);
  208.     if (wG) CloseWindow(wG);
  209.     if (DosBase) CloseLibrary(DosBase);
  210.     if (GfxBase != NULL) CloseLibrary(GfxBase);
  211.     if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  212.     exit(how);
  213.  
  214.  /* exit codes 
  215.   * 0  User requested
  216.   * 10 graphics lib open fail
  217.   * 11 intuition lib open fail
  218.   * 12 main window open fail
  219.   * 13 _abort() called
  220.   * 14 Bad CLI args
  221.   * 16 Dos lib open fail
  222.   */
  223. }
  224.  
  225.  
  226. /*
  227.  * do_pick : handle chain of menu selections
  228.  */
  229.  
  230. do_pick(menunum)
  231. USHORT menunum;
  232. {
  233. struct MenuItem *item, *ItemAddress();
  234.     while (menunum != MENUNULL)
  235.         {
  236.         switch(MENUNUM(menunum))
  237.             {
  238.             case 0:     /* Project Menu */
  239.             switch(ITEMNUM(menunum))
  240.                 {
  241.                 case 0: /* Load */
  242.                     do_load();
  243.                     break;
  244.                 case 1: /* Save */
  245.                     do_save();
  246.                     break;
  247.                 case 2: /* Print */
  248.                     do_print();
  249.                     break;
  250.                 case 4: /* About */
  251.                     about();
  252.                     break;
  253.                 case 3: /* Help */
  254.                     help();
  255.                     break;
  256.                 case 5: /* Quit */
  257.                     done(0);
  258.                 }
  259.             break;
  260.             default:    /* What's this garbage ? */
  261.                 menunum = MENUNULL;
  262.             }       /* end switch MENUNUM  */
  263.  
  264.         /* Get chain to next selection. NextSelect contains another item
  265.            when the user makes multiple menu selections             */
  266.         item = ItemAddress(&MenuList1,(long) menunum);
  267.         menunum = item->NextSelect;
  268.         }
  269. }
  270.  
  271.  
  272. /*
  273.  *  Validate input and calculate new balance
  274.  */
  275.  
  276. calc_it()
  277. /*
  278.  *  Adapted from:
  279.  *
  280.  *     ira.c :  Calculate Nest-Egg at retirement from the
  281.  *              following input:
  282.  *
  283.  *     Beginning Balance
  284.  *     Anual percentage rate
  285.  *     Annual deposit
  286.  *     Years till retirement
  287.  *
  288.  *   By Joel Swank 8/18/89
  289.  */
  290.  
  291. {
  292.     long i;
  293.     double xapr;
  294.  
  295.     if (!batch)  if (!get_values()) return;
  296.  
  297.     xapr = 1.0 + apr/100.0;
  298.     ne = bb;
  299.     for (i=0; i<yrs; i++)
  300.        {
  301.        ne += ad;
  302.        ne *= xapr;
  303.        }
  304.  
  305.     if (batch) {
  306.         printf("For Beginning balance = $%-12.2f\n",bb);
  307.         printf("Annual percentage Rate = %2.2f%%\n",apr);
  308.         printf("Annual deposit = $%-12.2f\n",ad);
  309.         printf("Nest-Egg after %ld years is $%-12.2f\n",yrs,ne);
  310.     } else {
  311.         bb = ne;
  312.         put_values();
  313.         }
  314.  
  315. }
  316.  
  317. /*
  318.  *  Get input data from string requesters
  319.  */
  320.  
  321. get_values()
  322. {
  323.     int i;
  324.  
  325.     i = get_float(BalanceGadSIBuff,&bb) ;
  326.     if ( !i || bb < MINBB)
  327.         {
  328.         messagetxt.IText = (UBYTE *) balancemsg;
  329.         AutoRequest(wG,&messagetxt,0L,&oktxt,0L,0L,300L,75L);
  330.         return FALSE;
  331.         }
  332.  
  333.     i = get_float(InterestGadSIBuff,&apr);
  334.     if ( !i || apr < MINAPR || apr > MAXAPR)
  335.         {
  336.         messagetxt.IText = (UBYTE *) interestmsg;
  337.         AutoRequest(wG,&messagetxt,0L,&oktxt,0L,0L,300L,75L);
  338.         return FALSE;
  339.         }
  340.  
  341.     i = get_float(DepositGadSIBuff,&ad);
  342.     if ( !i || ad < MINAD )
  343.         {
  344.         messagetxt.IText = (UBYTE *) depositmsg;
  345.         AutoRequest(wG,&messagetxt,0L,&oktxt,0L,0L,300L,75L);
  346.         return FALSE;
  347.         }
  348.  
  349.     yrs = YearsGadSInfo.LongInt;
  350.     if (yrs < MINYRS)
  351.         {
  352.         messagetxt.IText = (UBYTE *) yearsmsg;
  353.         AutoRequest(wG,&messagetxt,0L,&oktxt,0L,0L,300L,75L);
  354.         return FALSE;
  355.         }
  356.  
  357.     return TRUE;
  358. }
  359.  
  360. /*
  361.  *  Get a floating point number from an ASCII string.
  362.  *    Return TRUE for good number, FALSE for bad.
  363.  */
  364.  
  365. get_float(string,val)
  366. char *string;
  367. double *val;
  368. {
  369.     int i;
  370.  
  371.     i = sscanf(string,"%E",val);
  372.     if (i == 1) return TRUE;
  373.     else return FALSE;
  374. }
  375.  
  376. /*
  377.  *  Put values back into their string requesters
  378.  */
  379.  
  380. put_values()
  381. {
  382.     YearsGadSInfo.LongInt = yrs;
  383.     sprintf(YearsGadSIBuff,"%d",YearsGadSInfo.LongInt);
  384.     if (bb >= 1000000.0) sprintf(BalanceGadSIBuff,"%.6e",bb);
  385.     else sprintf(BalanceGadSIBuff,"%.2f",bb);
  386.     sprintf(InterestGadSIBuff,"%.3f",apr);
  387.     sprintf(DepositGadSIBuff,"%.2f",ad);
  388.     if (wG) redraw_scr();
  389. }
  390.  
  391. /*
  392.  * Redraw Window
  393.  */
  394.  
  395. redraw_scr()
  396. {
  397.     RemoveGList(wG,&GadgetList1,-1L); /* remove all gadgets */
  398.     SetAPen(rpG,0L); /* clear the window */
  399.     RectFill(rpG,2L,11L,(long)(wG->Width-3),(long)(wG->Height-2));
  400.     AddGList(wG,&GadgetList1,0L,-1L,NULL);  /* put back gadgets */
  401.     RefreshGList(&GadgetList1,wG,NULL,-1L); /* redraw the gadgets */
  402.     PrintIText(rpG,&IntuiTextList1,0L,0L); /* write window text */
  403.     SetAPen(rpG,1L);  /* set draw color */
  404. }
  405.  
  406.  
  407.  
  408. /*
  409.  *    Print the data
  410.  */
  411.  
  412. do_print()
  413. {
  414.     int i;
  415.     FILE *fp;
  416.  
  417.     if (!get_values()) return;
  418.  
  419.     while ((fp = fopen("PRT:","w")) == NULL)
  420.         {
  421.         if (AutoRequest(wG,&prfailtxt,&retrytxt,&cantxt,
  422.             0L,0L,300L,75L)) continue;
  423.         return;
  424.         }
  425.  
  426.     fprintf(fp,"%s\n",header);
  427.     fprintf(fp,"Balance = $%-20.2f\n",bb);
  428.     fprintf(fp,"Annual percentage Rate = %2.3f%%\n",apr);
  429.     fprintf(fp,"Annual deposit = $%-20.2f\n",ad);
  430.     fprintf(fp,"Years = $%d\n",yrs);
  431.  
  432.     fclose(fp);
  433. }
  434.  
  435.  
  436. /*
  437.  *    Load data from an ASCII file
  438.  */
  439.  
  440. do_load()
  441. {
  442.     FILE *fp;
  443.  
  444.     select_file(0);
  445.     if (filename[0] == '\0') return;
  446.  
  447.     while ((fp = fopen(filename,"r")) == NULL)
  448.         {
  449.         infailtxt2.IText = (UBYTE *) filename;
  450.         if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
  451.             0L,0L,reqlen(filename),75L)) continue;
  452.         return;
  453.         }
  454.     read_file(fp);
  455.     fclose(fp);
  456. }
  457.  
  458.  
  459. /*
  460.  *    Read in data from open file
  461.  */
  462.  
  463. read_file(fp)
  464. FILE *fp;
  465. {
  466.     int i;
  467.  
  468.     i = fscanf(fp," %20F, %7F, %20F, %d",&bb,&apr,&ad,&yrs);
  469.     if (i != 4 || apr > MAXAPR || bb < MINBB || ad < MINAD)
  470.         {
  471.         infailtxt2.IText = (UBYTE *) filename;
  472.         AutoRequest(wG,&badfiletxt,0L,&oktxt,0L,0L,reqlen(filename),75L);
  473.         return(FALSE);
  474.         }
  475.  
  476.     put_values();
  477. }
  478.  
  479. /*
  480.  *    Save the current data in an ASCII file
  481.  */
  482.  
  483. do_save()
  484. {
  485.     FILE *fp;
  486.     int i;
  487.  
  488.     if (!get_values()) return;
  489.  
  490.     select_file(1);
  491.     if (filename[0] == '\0') return;
  492.  
  493.     while ((fp = fopen(filename,"w")) == NULL)
  494.         {
  495.         infailtxt2.IText = (UBYTE *) filename;
  496.         if (AutoRequest(wG,&infailtxt,&retrytxt,&cantxt,
  497.             0L,0L,reqlen(filename),75L)) continue;
  498.         return;
  499.         }
  500.     AddFileIOName(FIOSupp,filename); /* tell FIO about new file */
  501.  
  502.     fprintf(fp,"%.2f,%.3f,%.2f,%d",bb,apr,ad,yrs);
  503.     fprintf(fp,"\n");
  504.     fclose(fp);
  505.  
  506. }
  507.  
  508.  
  509. /*
  510.  * Select a file
  511.  */
  512.  
  513. select_file(io)
  514. int io;
  515. {
  516.     struct Window *OpenWindow(), *wF = NULL;
  517.     struct FileLock *lock = NULL;
  518.  
  519.     ClearMenuStrip(wG);
  520.  
  521.     if (NULL == FIOSupp)
  522.         if (NULL == (FIOSupp = GetFileIOSupport()))
  523.             {
  524.             AutoRequest(wG,&fiofailtxt,0L,&cantxt,0L,0L,300L,75L) ;
  525.             SetMenuStrip(wG,&MenuList1);    /* re-attach my Menu */
  526.             return;
  527.             }
  528.  
  529.     /* set up title for file requester */
  530.     if (io == 0) FIOSupp->ReqTitle = (UBYTE *) load_title;
  531.     else FIOSupp->ReqTitle = (UBYTE *) save_title;
  532.  
  533.     wF = OpenWindow(&NewWindowStructure3);    /* open the window */
  534.     if ( wF == NULL )
  535.         {
  536.         AutoRequest(wG,&winfailtxt,0L,&oktxt,0L,0L,300L,75L);
  537.         SetMenuStrip(wG,&MenuList1);    /* re-attach my Menu */
  538.         return;
  539.         }
  540.  
  541.     filename[0] = '\0';
  542.     if (GetFileIOName(FIOSupp,wF))
  543.         BuildFileIOPathname(FIOSupp,filename);
  544.  
  545.     if (wF) CloseWindow(wF);
  546.     if (lock) UnLock(lock);
  547.     SetMenuStrip(wG,&MenuList1);    /* attach my Menu */
  548. }
  549.  
  550.  
  551. /*
  552.  *  Calculate size of requester needed for given filename
  553.  */
  554.  
  555. reqlen(filename)
  556. char *filename;
  557. {
  558.     int r;
  559.     r = TextLength(rpG,filename,strlen(filename))+50;
  560.     if (r < 300) r = 300;
  561.     if (r > 640) r = 640;
  562.     return (r) ;
  563. }
  564.  
  565. #ifdef AZTEC_C
  566. _abort()
  567. {
  568.     done(13);
  569. }
  570. #endif
  571.